

import { Comp } from "../m/CompDef";
import { GpEntity } from "./GpEntity";
import GpHeroHud from "./GpHeroHud";
import { MathUtils, Vect3 } from "../../common/MathUtils";
import { DamageEventInfo } from "../m/systems/battle/BattleSystem";
import { GpWorldLayer } from "./GpWorld";
import { HeroActionEventData } from "../m/GpDef";
import { GpCfg } from "../m/GpCfgDef";


export enum EHeroAniName {
    idle = "animation",
    move = "move",
    atact = "atact",
    atact2 = "atact2",
    atact3 = "atact3",
}
import { _decorator, Color, Component, isValid, Label, Node, sp, Tween, tween, UITransform, Vec3 } from 'cc';
import { AssetsManager } from "../../../../extensions/cocos-scaffold-3x/assets/manger/AssetsManager";
import { BaseComponent } from "../../../../extensions/cocos-scaffold-3x/assets/ui/base/BaseComponent";
import { ShakeComponent } from "../../../../extensions/cocos-scaffold-3x/assets/ui/ShakeComponent";

import { gg } from "../../../Game";
import { EcsEntity } from "ecs-ts";
const { ccclass, property } = _decorator;

@ccclass
export default class GpHero extends BaseComponent {

    @property(GpHeroHud)
    gpHeroHud: GpHeroHud = null;

    @property(sp.Skeleton)
    ske: sp.Skeleton = null

    @property(Label)
    targetPosLabel: Label = null;


    @property(Node)
    shadow: Node = null;

    colorArr = [
        new Color(200, 100, 100),
        new Color(100, 200, 100),
        new Color(100, 100, 200),
    ]

    isMaster = false

    battleInfo: Comp.Battle.BattleInfo

    entity: GpEntity

    ecsEntity: EcsEntity

    move: Comp.Move

    skeScale = 0.1

    onInit(): void {
        const entity = this.node.getComponent(GpEntity)
        this.entity = entity
        const ecsEntity = entity.ecsEntity
        this.move = ecsEntity.component(Comp.Move)
        this.ecsEntity = ecsEntity
        const force = ecsEntity.component(Comp.Force)
        const transform = entity.transform
        this.battleInfo = ecsEntity.component(Comp.Battle.BattleInfo)
        // console.log("GpHero onInit", force.value);
        entity.renderRoot.scale = new Vec3(1, 1, 1)

        this.ske.color = Color.WHITE

        // entity.renderRoot.color = this.colorArr[(this.colorArr.length - 1) % (this.colorArr.length - 1 + force.value)]
        // entity.renderRoot.children.forEach(i => { i.color = this.colorArr[(this.colorArr.length - 1) % (this.colorArr.length - 1 + force.value)] })
        this.isMaster = force.value == 0
        entity.renderRoot.getComponent(UITransform).setContentSize(transform.radius * 2, transform.radius * 2)
        this.setupHud()
        this.targetPosLabel.string = "" + ecsEntity.id
        this.targetPosLabel.node.active = false
        this.targetPosLabel.node.parent = this.entity.prop.world.hudLayer

        const scale = this.entity.transform.radius / 15
        this.ske.node.scale = new Vec3(scale * this.skeScale, scale * this.skeScale, 1)


        this.node.getComponentInChildren(ShakeComponent).defaultAmplitude = Math.floor(this.entity.transform.radius / 8) + 1

        this.ske.node.active = false
        const skeName = entity.prop.ecsEntityId == 10000 ? "charactor" : "charactor"
        this.ske.skeletonData = null
        AssetsManager.setSpineSke(this.ske, "gameplay/v/hero/spine/" + skeName).then(() => {
            if (isValid(this.node)) {
                this.ske.node.active = true
                // this.ske.setMix(EHeroAniName.idle, EHeroAniName.atact, 0.2)
                // this.ske.setMix(EHeroAniName.idle, EHeroAniName.move, 0.2)

                // this.ske.setMix(EHeroAniName.atact, EHeroAniName.idle, 0.1)
                // this.ske.setMix(EHeroAniName.atact, EHeroAniName.move, 0.8)

                // this.ske.setMix(EHeroAniName.atact2, EHeroAniName.idle, 0.2)
                // this.ske.setMix(EHeroAniName.atact2, EHeroAniName.move, 0.2)

                // this.ske.setMix(EHeroAniName.atact3, EHeroAniName.idle, 0.2)
                // this.ske.setMix(EHeroAniName.atact3, EHeroAniName.move, 0.2)

                // this.ske.setMix(EHeroAniName.move, EHeroAniName.atact, 0.2)
                // this.ske.setMix(EHeroAniName.move, EHeroAniName.idle, 0.2)

            }
        })


    }

    onEnable() {
        const entity = this.node.getComponent(GpEntity)
        const ecsEntity = entity.ecsEntity
        if (ecsEntity) {
            this.setupHud()
        }
    }


    setupHud() {
        if (this.entity) {
            this.gpHeroHud.init(this)
            // this.gpHeroHud.node.parent = this.entity.prop.world.hudLayer
            this.gpHeroHud.node.active = true

            this.shadow.active = true
            this.shadow.parent = this.entity.prop.world.getLayer(GpWorldLayer.shadow)
            this.shadow.scale = new Vec3(this.entity.transform.radius / 15, this.entity.transform.radius / 15, this.entity.transform.radius / 15)
        }
    }

    protected onDisable(): void {
        // this.gpHeroHud.node.setPosition(-100000, -100000)
        // this.gpHeroHud.node.active = false
        this.targetPosLabel.node.active = false

        this.shadow.setPosition(-100000, -100000)
        this.shadow.active = false

    }

    setSkeAni(animation: string, timeScale = 1) {
        if (this.ecsEntity.id == 10000) {
            // console.log("setSkeAni", animation, timeScale);

        }
        this.ske.timeScale = timeScale

        this.ske.animation != animation && (this.ske.animation = animation)

    }


    tempVec3 = new Vect3()

    updateTargetPosLabel() {
        this.targetPosLabel.node.active = !Vect3.equals(this.move.targetPos, Vect3.ZERO)
        this.targetPosLabel.node.setPosition(this.move.targetPos.x, this.move.targetPos.y)
    }
    protected update(dt: number): void {
        // this.updateTargetPosLabel()
        if (this.ske.node.active) {
            const orientation = this.entity.transform.orientation
            const scale = this.skeScale * (this.entity.transform.radius / 15)
            this.ske.node.scale = new Vec3(this.ske.node.scale.x, scale, this.ske.node.scale.z)

            if (orientation.x > 0) {
                this.ske.node.scale = new Vec3(-scale, this.ske.node.scale.y, this.ske.node.scale.z)
            } else if (orientation.x < 0) {
                this.ske.node.scale = new Vec3(scale, this.ske.node.scale.y, this.ske.node.scale.z)
            }

            if (!this.actionTween || !this.ecsEntity.component(Comp.HeroAction).playing) {
                if (Vect3.distance(this.lateUpdatePos, this.node.position) < 0.1) {
                    const ani = this.ske.findAnimation("daiji")
                    if (ani) {
                        this.setSkeAni("daiji")
                    } else {
                        this.setSkeAni("animation")
                    }
                } else {
                    const ani = this.ske.findAnimation("yidong")
                    if (ani) {
                        this.setSkeAni("yidong")
                    } else {
                        this.setSkeAni("animation")
                    }
                }
            }


            Vect3.set(this.lateUpdatePos, this.node.position)


        }
        // this.shadow.angle = MathUtils.vectorToAngle(this.entity.transform.orientation) - 90
        this.shadow.setPosition(this.node.position.x + this.ske.node.position.x, this.node.position.y + this.ske.node.position.y, 0)
        // if (this.ecsEntity.id == 10000) {
        //     console.log("this.actionTween", !!this.actionTween, this.ecsEntity.component(Comp.HeroAction).id);

        // }


    }
    lateUpdatePos: Vect3 = new Vect3()

    actionTween: Tween<any> = null

    clearActionTween() {
        if (this.actionTween) {
            this.actionTween.stop()
            this.actionTween = null
        }
    }

    onActionStart(data: HeroActionEventData) {
        this.clearActionTween()
        this.entity.renderRoot.scale = new Vec3(1, 1, 1)

        const actionCfg = gg.cfgById(GpCfg.Action, data.action.id)
        const ani = this.ske.findAnimation(actionCfg.aniName)
        const attStartDuration = data.action.duration / 3000
        const attEndDuration = data.action.duration / 1000

        if (ani) {
            const scale = ani.duration / actionCfg.duration
            this.setSkeAni(actionCfg.aniName, scale)
            this.actionTween = tween(this.entity.renderRoot).to(attStartDuration, { scale: new Vec3(1, 1, 1) }, { easing: "expoIn" }).to(attEndDuration, { scale: new Vec3(1, 1, 1) }, { easing: "expoOut" }).start()
            // console.log(ani.name,ani.duration);
        } else {
            this.actionTween = tween(this.entity.renderRoot).to(attStartDuration, { scale: new Vec3(1.25, 1.25, 1.25) }, { easing: "expoIn" }).to(attEndDuration, { scale: new Vec3(1, 1, 1) }, { easing: "expoOut" }).start()
        }
    }

    onActionEnd(data: HeroActionEventData) {
        let ani = this.ske.findAnimation("daiji") || this.ske.findAnimation("animation")

        this.setSkeAni(ani.name)

        this.clearActionTween()

    }


    hitColor = new Color(255, 150, 150)

    onAttPointTriggered(entity: EcsEntity, battleInfo: Comp.Battle.BattleInfo, target: EcsEntity, targetBattleInfo: Comp.Battle.BattleInfo) {

    }

    onDamage(eventInfo: DamageEventInfo) {

        if (this.ecsEntity.component(Comp.Battle.BattleInfo).curHp <= 0) {
            this.setSkeAni(EHeroAniName.idle)
            this.gpHeroHud.node.active=false
        }

        this.ske.color = this.hitColor
        this.node.getComponentInChildren(ShakeComponent).shake()
        this.clearDamageTween()
        this.damageTween = tween(this.ske.node).delay(0.2).call(() => {
            this.ske.color = Color.WHITE
        }).start()
    }

    clearDamageTween() {
        if (this.damageTween) {
            this.damageTween.stop()
            this.damageTween = null
        }
    }

    damageTween: Tween<any> = null



}
